﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Media3D;
using BaseMod.Models;
using Microsoft.Win32;
using OfficeOpenXml;

namespace BaseMod.Views
{
    /// <summary>
    /// Interaction logic for BaseWindow
    /// </summary>
    public partial class BaseWindow : UserControl
    {
        public ObservableCollection<SplitEntity> SplitEntities { get; set; }
        public BaseWindow()
        {
            InitializeComponent();

            SplitEntities = new ObservableCollection<SplitEntity>();
            tbX1.Text = "3854.58";
            tbY1.Text = "8850";
            tbZ1.Text = "5521.2";

            tbX2.Text = "3854.58";
            tbY2.Text = "8850";
            tbZ2.Text = "1722.38";

            tbX3.Text = "3566.749";
            tbY3.Text = "8950.282";
            tbZ3.Text = "1417.58";

            tbX4.Text = "3137.831";
            tbY4.Text = "9099.718";
            tbZ4.Text = "1417.58";


        }

        private void BtnSplite_OnClick(object sender, RoutedEventArgs e)
        {
            var gridCol = false;

            if(string.IsNullOrWhiteSpace(TbSpliteChar.Text))
                return;
            var ofd = new OpenFileDialog();
            ofd.Filter = "TEXT file|*.txt";
            ofd.Multiselect = false;
            if (ofd.ShowDialog() == true)
            {
                var textLines = File.ReadAllLines(ofd.FileName);

                foreach (var line in textLines)
                {
                    var text = line.Trim();
                    if (string.IsNullOrEmpty(text)) continue;
                    var txtSps = text.Split(TbSpliteChar.Text);
                    if (txtSps.Length > 0)
                    {
                        var spe =new SplitEntity();
                        
                        for (int i = 0; i < txtSps.Length; i++)
                        {
                            if (i >= 15)
                            {
                                continue;
                            }
                            var _cp = $"C{i}";
                            var _cc = txtSps[i];

                            spe.GetType().GetProperty(_cp).SetValue(spe, _cc);
                        }
                        SplitEntities.Add(spe);
                    }
                }

                LtListView.ItemsSource = SplitEntities;
            }
        }

        private void BtnExportExcel_OnClick(object sender, RoutedEventArgs e)
        {
            if (SplitEntities != null && SplitEntities.Count > 0)
            {
                string path = $"{DateTime.Now.ToString("yyyyMMdd.HHmmsss")}.Split.xlsx";
                FileInfo fileInfo = new FileInfo(path);
                using (ExcelPackage package = new ExcelPackage(fileInfo))
                {
                    //创建sheet1
                    ExcelWorksheet sheet = package.Workbook.Worksheets.Add("sheet1");
                    for (int i = 0; i < SplitEntities.Count; i++)
                    {
                        InsertEntity(i + 1, sheet, SplitEntities[i]);
                    }
                    //保存
                    package.Save();
                }
            }
        }

        private void InsertEntity(int rowIndex, ExcelWorksheet sheet, SplitEntity entity)
        {
            sheet.Cells[rowIndex, 1].Value = entity.C0;
            sheet.Cells[rowIndex, 2].Value = entity.C1;
            sheet.Cells[rowIndex, 3].Value = entity.C2;
            sheet.Cells[rowIndex, 4].Value = entity.C3;
            sheet.Cells[rowIndex, 5].Value = entity.C4;
            sheet.Cells[rowIndex, 6].Value = entity.C5;
            sheet.Cells[rowIndex, 7].Value = entity.C6;
            sheet.Cells[rowIndex, 8].Value = entity.C7;
            sheet.Cells[rowIndex, 9].Value = entity.C8;
            sheet.Cells[rowIndex, 10].Value = entity.C9;
            sheet.Cells[rowIndex, 11].Value = entity.C10;
            sheet.Cells[rowIndex, 12].Value = entity.C11;
            sheet.Cells[rowIndex, 13].Value = entity.C12;
            sheet.Cells[rowIndex, 14].Value = entity.C13;
            sheet.Cells[rowIndex, 15].Value = entity.C14;

        }

        private void BtnSplite2_OnClick(object sender, RoutedEventArgs e)
        {
            
        }

        private void BtnLonLatToTileInfo_OnClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace( TbLat.Text))
            {
                return;
            }
            if (string.IsNullOrWhiteSpace(TbLon.Text))
            {
                return;
            }
            if (string.IsNullOrWhiteSpace(TbZoom.Text))
            {
                return;
            }
            double dLat = 0.0, dLon = 0.0;
            int iZoom = 0;
            double.TryParse(TbLat.Text, out dLat);
            double.TryParse(TbLon.Text, out dLon);
            int.TryParse(TbZoom.Text, out iZoom);
            GlobalGRS globalGrs = new GlobalGRS();
            var tmsTileInfo = globalGrs.GPStoTMSTilexy(iZoom, dLon, dLat);
            var pts = globalGrs.GPStoGoogleTilexy(iZoom, dLon, dLat);

            var googleGps = globalGrs.TileIndexToGoogleLonLat(iZoom,pts.Column,pts.Row);

            //GoogleYtile=2zoom-TMSYtile-1

            var tmsGps = globalGrs.TileIndexToTMSLonLat(iZoom,tmsTileInfo.Column, tmsTileInfo.Row);
            TbTileInfo.Text = $"TMS TileInfo:X:{tmsTileInfo.Column},Y:{tmsTileInfo.Row},Z:{iZoom}===Goole TileXY X:{pts.Column},Y:{pts.Row}";
            TbTileToGPS.Text = $"Google Lon:{googleGps.Lng},Lat{googleGps.Lat};tms Lon{tmsGps.Lng},Lat{tmsGps.Lat}";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtJs_Click(object sender, RoutedEventArgs e)
        {
            double d1x = 0.0;
            double d1y = 0.0;
            double d1z = 0.0;

            double d2x = 0.0;
            double d2y = 0.0;
            double d2z = 0.0;

            double.TryParse(tbX1.Text, out d1x);
            double.TryParse(tbY1.Text, out d1y);
            double.TryParse(tbZ1.Text, out d1z);

            double.TryParse(tbX2.Text, out d2x);
            double.TryParse(tbY2.Text, out d2y);
            double.TryParse(tbZ2.Text, out d2z);

            double d3x = 0.0;
            double d3y = 0.0;
            double d3z = 0.0;

            double d4x = 0.0;
            double d4y = 0.0;
            double d4z = 0.0;

            double.TryParse(tbX3.Text, out d3x);
            double.TryParse(tbY3.Text, out d3y);
            double.TryParse(tbZ3.Text, out d3z);

            double.TryParse(tbX4.Text, out d4x);
            double.TryParse(tbY4.Text, out d4y);
            double.TryParse(tbZ4.Text, out d4z);


            if (d1x == 0 && d2x == 0 && d3x == 0 && d4x == 0 &&
                d1y == 0 && d2y == 0 && d3y == 0 && d4y == 0)
            {
                MessageBox.Show("请填入数据");
                return;
            }
            //var line1 = new Line3D(new Vector3(d1x, d1y, d1z), new Vector3(d2x, d2y, d2z));
            //var line2 = new Line3D(new Vector3(d3x, d3y, d3z), new Vector3(d4x, d4y, d4z));
            //if (LineIntersection3D.TryGetIntersection(line1, line2, out var intersection))
            //    TbResult.Text = $"交点坐标: ({intersection.X}, {intersection.Y}, {intersection.Z})";
            ////Console.WriteLine($"交点坐标: ({intersection.X}, {intersection.Y}, {intersection.Z})");
            //else 
            //    TbResult.Text = "无交点";

            ////Console.WriteLine("无交点");




            // 示例：两条相交直线
            var a1 = new BaseMod4.Vector3(d1x, d1y, d1z);
            var v1 = new BaseMod4.Vector3(d2x-d1x,d2y-d1y, d2z-d1z);

            var a2 = new BaseMod4.Vector3(d3x, d3y, d3z);
            var v2 = new BaseMod4.Vector3(d4x - d3x, d4y - d3y, d4z - d3z);

            var a3 = new BaseMod4.Vector3(d2x, d2y, d2z);
            var a4 = new BaseMod4.Vector3(d4x, d4y, d4z);


            var resultOneArea = BaseMod4.Lineint2.ArePointsCoplanar(a1, a2, a3, a4);

            if (BaseMod4.Lineint2.FindLineIntersection(a1, v1, a2, v2, out var point))
                Console.WriteLine($"交点坐标: ({point.X}, {point.Y}, {point.Z})");
            else
                Console.WriteLine("直线不相交");


            BaseMod.Point3D p1 = new BaseMod.Point3D(d1x, d1y, d1z);
            BaseMod.Point3D p2 = new BaseMod.Point3D(d2x, d2y, d2z);
            BaseMod.Point3D p3 = new BaseMod.Point3D(d3x, d3y, d3z);
            BaseMod.Point3D p4 = new BaseMod.Point3D(d4x, d4y, d4z);
            var rsdf = IsCoplanar(p1, p2, p3, p4);

            var result3Point = Demo4.PlaneEquationCalculator.CalculatePlaneEquation(p1, p2, p3);
            Console.WriteLine($"{result3Point}");
            //Ax + By + Cz + D = 0，其中：


        }


        public static BaseMod.Point3D Subtract(BaseMod.Point3D a, BaseMod.Point3D b)
        {
            return new Point3D(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
        }

        //向量叉乘
        public static BaseMod.Point3D CrossProduct(BaseMod.Point3D v1, BaseMod.Point3D v2)
        {
            return new BaseMod.Point3D(
                v1.Y * v2.Z - v1.Z * v2.Y,
                v1.Z * v2.X - v1.X * v2.Z,
                v1.X * v2.Y - v1.Y * v2.X
            );
        }

        //向量点乘
        public static double DotProduct(BaseMod.Point3D v1, BaseMod.Point3D v2)
        {
            return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
        }

        //共面判断函数
        public static bool IsCoplanar(BaseMod.Point3D p1, BaseMod.Point3D p2, BaseMod.Point3D p3, BaseMod.Point3D p4)
        {
            // 构造三个向量 
            BaseMod.Point3D v1 = Subtract(p2, p1);
            BaseMod.Point3D v2 = Subtract(p3, p1);
            BaseMod.Point3D v3 = Subtract(p4, p1);

            // 计算叉乘和点乘
            BaseMod.Point3D cross = CrossProduct(v1, v2);
            double volume = Math.Abs(DotProduct(cross, v3));

            // 设置误差阈值（1e-8）
            const double epsilon = 1e-8;
            return volume < epsilon;
        }

    }
}
